package servidores;

import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.Socket;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.List;
import java.io.IOException;

public class ThreadClientePedidos extends Thread {
   
    private Socket socketClientePedidos;
    private ObjectInputStream flujoEntrada;
    private ObjectOutputStream flujoSalida;
    private List <Socket> listaClientesPedidos;
    
    private static final String JDBC_DRIVER = "sun.jdbc.odbc.JdbcOdbcDriver";        
    private static final String DATABASE_URL = "jdbc:odbc:dbSO";
	private static final String QUERY_COMPRA = "select stock from Libros where id_libro = ?";
	private static final String UPDATE_COMPRA = "update Libros set stock = stock - 1 where id_libro = ?";
	private Connection connection;
	private Statement statement;
	private PreparedStatement pstatement;
    
    public ThreadClientePedidos(Socket socketClientPedidos, List<Socket> listaClientsPedidos) throws IOException {
        this.socketClientePedidos = socketClientPedidos;
	    this.flujoSalida = new ObjectOutputStream(socketClientPedidos.getOutputStream());    
    	this.flujoEntrada = new ObjectInputStream(socketClientPedidos.getInputStream()); 
        this.listaClientesPedidos = listaClientsPedidos;
		try {
			Class.forName(JDBC_DRIVER);
			this.connection = DriverManager.getConnection(DATABASE_URL,"root","sergio");
			this.statement = connection.createStatement();
		} catch (ClassNotFoundException e) {
			sendToClient("Error al conectarse a la base de datos: Driver",flujoSalida);
		} catch (SQLException e) {
			sendToClient("Error al conectarse a la base de datos: Connect",flujoSalida);
		}

    }
   
    public void run () {
        try {
            while (true) {
                String mensaje = flujoEntrada.readUTF();
                System.out.println("BackEnd-Pedidos: Ejecutando " + mensaje + "[threadId: " + this.getId() + "]");
                if ("buyBook".equalsIgnoreCase(mensaje.substring(0,7))) {
                	try {
                	    sendToClient(setComprarLibros(mensaje.substring(8)),flujoSalida);
					} catch (SQLException e) {
                	    sendToClient("Error setComprarLibros(id_Libro)",flujoSalida);
						e.printStackTrace();
					}
                }
            }
        }
        catch (IOException ex) {
        	System.out.println("BackEnd-Pedidos: Un Cliente se ha desconectado [threadId: " + this.getId() + "]");
        	//ex.printStackTrace();
        }
        finally {
        	listaClientesPedidos.remove(this.socketClientePedidos);
        	try {
				desconectar();
			} catch (SQLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
            cerrarFlujos();
        }
    }
    
    private void sendToClient(Object mensaje, ObjectOutputStream flujoSalida) {
        try {
            flujoSalida.writeObject(mensaje);
            flujoSalida.flush();
        }    
        catch (IOException ex) {
        	System.out.println("BackEnd-Pedidos: Error en sendToClient [threadId: " + this.getId() + "]");
            ex.printStackTrace();                 
        } 
    } 

    private void cerrarFlujos() { 
        try {
             flujoEntrada.close();
             flujoSalida.close();
             socketClientePedidos.close();
        }
        catch (IOException ex) {
        	System.out.println("BackEnd-Pedidos: Error en cerrarFlujos [threadId: " + this.getId() + "]");
        	ex.printStackTrace();
        }        
    }
    
	public Object setComprarLibros(String idLibro) throws SQLException {
		List <String>  listaLibros = new ArrayList<String>();
		
		this.pstatement = connection.prepareStatement(QUERY_COMPRA);
		this.pstatement.setInt(1, Integer.parseInt(idLibro));
		
		ResultSet datosRS = this.pstatement.executeQuery();
		
		datosRS.next();
		if (datosRS.getInt("stock") > 0 ) {
			this.pstatement = connection.prepareStatement(UPDATE_COMPRA);
			this.pstatement.setString(1, idLibro);
			int ret = pstatement.executeUpdate();
			if (ret == 1) listaLibros.add("YC");
			else if (ret == 0) listaLibros.add("NO");
			else if (ret > 1) listaLibros.add("NO");
		}
		else {
			listaLibros.add("NS");
		}
		
		return (Object) listaLibros;
	}
	
	private void desconectar() throws SQLException {
	        statement.close();
		    connection.close();
	}
}
